# -*- coding: utf-8 -*-
# Nirvana Dict
# Copyright (C) 2007 Nicholas Ding
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import os
import gtk
import pygtk
pygtk.require('2.0')
import urllib2
from elementtree import ElementTree as et

class DictProxy(object):
    '''
    字典查询类，通过 Dict.CN 的 API 查询单词解释
    '''

    def query(self, word):
        '''
        查询单词
        API 地址 - http://dict.cn/ws.php?utf8=true&q=word。
        '''
        f = urllib2.urlopen('http://dict.cn/ws.php?utf8=true&q=%s' % word)
        return f.read()

class DictWindow(object):
    '''
    字典主窗口
    +----------------------------------+
    | Search: |                        |
    +----------------------------------+
    | Word ......                      |
    |                                  |
    |                                  |
    |                                  |
    +----------------------------------+
    '''
    def entry_key_press_event(self, widget, event, data=None):
        if event.keyval == 65293:
            self.update_explain()
    
    def delete_event(self, widget, event, data=None):
        self.window.hide()
        return True

    def close_application(self, widget, data=None):
        gtk.main_quit()

    def window_show(self, window, event, data=None):
        self.word_entry.grab_focus()
        
    def window_hide(self, accel_group, acceleratable, keyval, modifiers):
        self.window.hide()
    
    def show_window(self, data):
        self.window.show()

    def search_button_press(self, event, data):
        self.update_explain()

    def popup_menu(self, status_icon, button, activate_time, data=None):
        menu = gtk.Menu()
        quit_item = gtk.MenuItem()
        quit_item.add(self.create_image_menu('退出', os.path.join(os.path.dirname(__file__), 'resources', 'go.png')))
        quit_item.connect_object('activate', gtk.Widget.destroy, self.window)
        menu.append(quit_item)
        quit_item.show()
        menu.show()
        menu.popup(None, None, gtk.status_icon_position_menu, gtk.gdk.BUTTON_PRESS, activate_time, self.status_icon)
    
    def create_image_label(self, label_text, image_file):
        box = gtk.HBox(False, 0)
        image = gtk.Image()
        image.set_from_file(image_file)
        label = gtk.Label(label_text)
        box.pack_start(image, False, False, 3)
        box.pack_start(label, False, False, 3)
        image.show()
        label.show()
        box.show()
        return box
    
    def create_image_menu(self, label_text, image_file):
        box = gtk.HBox(False, 0)
        image = gtk.Image()
        image.set_from_file(image_file)
        label = gtk.Label(label_text)
        box.pack_start(image, False, False, 3)
        box.pack_start(label, False, False, 3)
        image.show()
        label.show()
        box.show()
        return box
    
    def update_explain(self):
        if self.word_entry.get_text():
            explain = self.proxy.query(self.word_entry.get_text())
            if explain.find('Not Found') > -1:
                explain = self.proxy.query('[' + self.word_entry.get_text() + ']')
                self.word_entry.grab_focus()
            text = []
            sugg = []
            root = et.XML(explain)
            need_correct = False
            for c in root.getchildren():
                if c.tag == 'pron':
                    text.append('[%s]' % c.text)
                elif c.tag == 'def':
                    text.append(c.text)
                elif c.tag == 'sugg':
                    sugg.append(c.text)
            if sugg:
                out = '对不起,这个单词没找到!\n您要查找的是不是:\n' \
                    + '\n'.join(['%s. %s' % (i + 1, s) for i, s in enumerate(sugg)])
            else:
                out = '\n'.join(text)
            self.main_textview.get_buffer().set_text(out)

    def __init__(self):
        self.proxy = DictProxy()
        self.init_GUI()

    def init_GUI(self):
        # main window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_title("Dict.CN 字典助手 － Developed by Nirvana Studio")
        self.window.set_border_width(5)
        self.window.set_default_size(300, 200)
        self.window.connect('delete_event', self.delete_event)
        self.window.connect('destroy', self.close_application)
        self.window.connect('window-state-event', self.window_show)
        
        acc = gtk.AccelGroup()
        acc.connect_group(ord('H'), gtk.gdk.CONTROL_MASK, gtk.ACCEL_LOCKED, self.window_hide)
        self.window.add_accel_group(acc)
        #acc.connect()
        # self.window.connect('key-press-event', self.window_hide)

        vbox1 = gtk.VBox(False, 1)
        hbox1 = gtk.HBox(False, 0)
        self.window.add(vbox1)
        vbox1.pack_start(hbox1, False, True, 0)
        
        # label
        hbox1.pack_start(self.create_image_label('搜索: ', os.path.join(os.path.dirname(__file__), 'resources', 'search.png')), False, True, 0)
        
        # work input
        self.word_entry = gtk.Entry()
        self.word_entry.connect('key_press_event', self.entry_key_press_event)
        self.word_entry.show()
        hbox1.pack_start(self.word_entry, True, True, 0)
        
        # creates textview
        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        sw.show()
        self.main_textview = gtk.TextView()
        self.main_textview.show()
        sw.add(self.main_textview)
        vbox1.pack_start(sw, True, True, 0)
        
        # adds a icon on the task try
        self.status_icon = gtk.StatusIcon()
        self.status_icon.set_from_file(os.path.join(os.path.dirname(__file__), 'resources', 'book.png'))
        self.status_icon.connect('activate', self.show_window)
        self.status_icon.connect('popup_menu', self.popup_menu)
        
        hbox1.show()
        vbox1.show()
        self.window.show()

    def main(self):
        gtk.main()

if __name__ == '__main__':
    proxy = DictProxy()
    #proxy.query('dict')
    #proxy.query('almost')
    w = DictWindow()
    w.main()